#include <iostream>
#include <string>
#include <vector>
#include <fstream>

#include <gtest/gtest.h>

#include "dcmfactory.h"
#include "networkdefine.h"
#include "printdefine.h"
#include "datasetdefine.h"
#include "imagedefine.h"


namespace {
    class DicomTools :
        public testing::Test
    {};

    int RDF2DcmTest()
    {
        std::shared_ptr<IDataSet> dataset = DCMFactory::CreateDataSetInstance();
        std::ifstream iodStream("../../../local/config/mr_iod.json");
        if (!iodStream.is_open()) {
            return -1;
        }
        std::istreambuf_iterator<char> beg(iodStream), end;
        std::string str(beg, end);
        iodStream.close();
        if (!dataset->ParseIODString(str)) {
            return -1;
        }

        //Patient
        if (!dataset->Set("PatientName", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientBirthDate", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientSex", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientID", "test")) {
            return -1;
        }
        //General Study
        if (!dataset->Set("StudyInstanceUID")) {//internal general
            return -1;
        }
        if (!dataset->Set("StudyDate", "test")) {
            return -1;
        }
        if (!dataset->Set("StudyTime", "test")) {
            return -1;
        }
        if (!dataset->Set("ReferringPhysicianName", "test")) {
            return -1;
        }
        if (!dataset->Set("StudyID", "test")) {
            return -1;
        }
        if (!dataset->Set("AccessionNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("StudyDescription", "test")) {
            return -1;
        }
        //Patient Study
        if (!dataset->Set("PatientAge", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientWeight", "test")) {
            return -1;
        }
        //General Series
        if (!dataset->Set("SeriesInstanceUID")) {//internal general
            return -1;
        }
        if (!dataset->Set("Modality", "MR")) {
            return -1;
        }
        if (!dataset->Set("SeriesNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("SeriesDate", "test")) {
            return -1;
        }
        if (!dataset->Set("SeriesTime", "test")) {
            return -1;
        }
        if (!dataset->Set("SeriesDescription", "test")) {
            return -1;
        }
        if (!dataset->Set("BodyPartExamined", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientPosition", "test")) {
            return -1;
        }
        if (!dataset->Set("ProtocolName", "test")) {
            return -1;
        }
        //General Image
        if (!dataset->Set("InstanceNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("ContentDate", "test")) {
            return -1;
        }
        if (!dataset->Set("ContentTime", "test")) {
            return -1;
        }
        if (!dataset->Set("ImageType", "ORIGINAL\\PRIMARY")) {
            return -1;
        }
        if (!dataset->Set("ImageComments", "test")) {
            return -1;
        }
        //Image Plane
        //Row Spacing \ Column Spacing
        if (!dataset->Set("PixelSpacing", "")) {
            return -1;
        }
        if (!dataset->Set("ImageOrientationPatient", "test")) {
            return -1;
        }
        if (!dataset->Set("ImagePositionPatient", "test")) {
            return -1;
        }
        if (!dataset->Set("SliceThickness", "test")) {
            return -1;
        }
        if (!dataset->Set("SliceLocation", "test")) {
            return -1;
        }
        //Image Pixel
        std::ifstream istream("../../../local/img/rdf", std::ios::binary);
        if (!istream.is_open()) {
            return -1;
        }
        istream.seekg(0, std::ios_base::end);
        std::streamoff dataSize = istream.tellg();
        char* data = new char[dataSize];
        if (nullptr == data) {
            return-1;
        }
        istream.seekg(0, std::ios_base::beg);
        istream.read(data, dataSize);
        istream.close();
        if (!dataset->Set("PixelData", (unsigned short*)data, (unsigned long)(256 * 256))) {//row * column
            return -1;
        }
        if (!dataset->Set("SamplesPerPixel", (unsigned short)1)) {
            return -1;
        }
        if (!dataset->Set("PhotometricInterpretation", "MONOCHROME2")) {
            return -1;
        }
        if (!dataset->Set("Rows", (unsigned short)256)) {
            return -1;
        }
        if (!dataset->Set("Columns", (unsigned short)256)) {
            return -1;
        }
        if (!dataset->Set("BitsAllocated", (unsigned short)16)) {
            return -1;
        }
        if (!dataset->Set("BitsStored", (unsigned short)16)) {
            return -1;
        }
        if (!dataset->Set("HighBit", (unsigned short)15)) {
            return -1;
        }
        if (!dataset->Set("PixelRepresentation", (unsigned short)0)) {
            return -1;
        }
        //MR Image
        if (!dataset->Set("SequenceName", "test")) {
            return -1;
        }
        if (!dataset->Set("FlipAngle", "test")) {
            return -1;
        }
        if (!dataset->Set("EchoNumbers", "test")) {
            return -1;
        }
        if (!dataset->Set("RepetitionTime", "test")) {
            return -1;
        }
        if (!dataset->Set("PixelBandwidth", "test")) {
            return -1;
        }
        if (!dataset->Set("TransmitCoilName", "test")) {
            return -1;
        }
        if (!dataset->Set("NumberOfAverages", "test")) {
            return -1;
        }
        unsigned short am[] = { 1,2 };
        if (!dataset->Set("AcquisitionMatrix", am, 2)) {
            return -1;
        }
        if (!dataset->Set("InPlanePhaseEncodingDirection", "test")) {
            return -1;
        }
        if (!dataset->Set("EchoTime", "test")) {
            return -1;
        }
        if (!dataset->Set("InversionTime", "test")) {
            return -1;
        }
        if (!dataset->Set("AcquisitionDuration", 1.1)) {
            return -1;
        }
        //SOP Common
        if (!dataset->Set("SOPInstanceUID")) {//internal general
            return -1;
        }
        if (!dataset->Set("SOPClassUID", "test")) {
            return -1;
        }
        if (!dataset->Set("SpecificCharacterSet", "ISO_IR 192")) {//ISO_IR 192 == utf-8
            return -1;
        }
        //VOI LUT
        if (!dataset->Set("WindowCenter", "")) {
            return -1;
        }
        if (!dataset->Set("WindowWidth", "")) {
            return -1;
        }
        //Frame of Reference
        if (!dataset->Set("FrameOfReferenceUID", "test")) {
            return -1;
        }
        if (!dataset->Set("PositionReferenceIndicator", "test")) {
            return -1;
        }
        //General Equipment
        if (!dataset->Set("Manufacturer", "test")) {
            return -1;
        }
        if (!dataset->Set("InstitutionName", "test")) {
            return -1;
        }
        if (!dataset->Set("ManufacturerModelName", "test")) {
            return -1;
        }
        //General Acquisition
        if (!dataset->Set("AcquisitionNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("AcquisitionDate", "test")) {
            return -1;
        }
        if (!dataset->Set("AcquisitionTime", "test")) {
            return -1;
        }
        //Private
        std::string privateCreator = "marvelstone";
        if (!dataset->SetPrivate("PRIVATE_CREATOR_MARVELSTONE", privateCreator)) {
            return -1;
        }
        if (!dataset->SetPrivate("PRIVATE_RDFDATAFORMAT", privateCreator, (unsigned short)3)) {
            return -1;
        }
        if (!dataset->SetPrivate("PRIVATE_RDFPARAMETER", privateCreator, "test")) {
            return -1;
        }
        if (!dataset->SetPrivate("PRIVATE_SCANID", privateCreator, "test")) {
            return -1;
        }

        //general dicom file
        if (!dataset->GeneralDCMFile("../../../local/img/rdf.dcm", DCM_TransferSyntax::EXS_LittleEndianExplicit)) {
            return -1;
        }

        return 0;
    }

    int responseCount = 0;
    void WorklistCallback(const NetworkStatus aStatus, const std::string& aResponse, const std::string& aDescription)
    {
        if (aStatus == NetworkStatus::Pending) {
            std::cout << aResponse << std::endl;
            responseCount++;
        } else if (aStatus == NetworkStatus::Failure) {
            std::cout << "query failed: " << aResponse << std::endl;
        }
    }

    int WorklistTest()
    {
        std::shared_ptr<INetwork> network = DCMFactory::CreateNetworkInstance();
        std::shared_ptr<IDataSet> dataset = DCMFactory::CreateDataSetInstance();

        std::ifstream iodStream("../../../local/config/worklist.json");
        if (!iodStream.is_open()) {
            return -1;
        }
        std::istreambuf_iterator<char> beg(iodStream), end;
        std::string str(beg, end);
        iodStream.close();
        if (!dataset->ParseIODString(str)) {
            return -1;
        }

        WorklistInfo worklist;
        worklist.myModality = "MR";
        worklist.myPatientAge = "";
        worklist.myPatientBirthDate = "";
        worklist.myPatientID = "";
        worklist.myPatientName = "";
        worklist.myPatientSex = "";
        worklist.myPatientSize = "";
        worklist.myPatientWeight = "";

        ServerInfo server;
        server.myHost = "worklist.fluxinc.ca";
        server.myPort = "1070";
        server.myTitle = "FLUX_WORKLIST";
        ServerInfo server1;
        server1.myHost = "127.0.0.1";
        server1.myPort = "5679";
        server1.myTitle = "DVTK_MW_SCU";
        network->BindWorklistCallback(WorklistCallback);
        if (!network->WorklistRequest(server1, worklist)) {
            return -1;
        }
        std::cout << "responseCount: " << responseCount << std::endl;

        return 0;
    }

    int EchoTest()
    {
        std::shared_ptr<INetwork> network = DCMFactory::CreateNetworkInstance();

        ServerInfo server;
        server.myHost = "127.0.0.1";
        server.myPort = "5678";
        server.myTitle = "IHEFULL";
        if (!network->EchoRequest(server)) {
            return -1;
        }

        return 0;
    }

    int EchoTLSTest()
    {
        std::shared_ptr<INetwork> network = DCMFactory::CreateNetworkInstance();

        ServerInfo server;
        server.myHost = "127.0.0.1";
        server.myPort = "63136";
        server.myTitle = "ACCEPTOR";
        network->SetTLS(
            "",
            "F:/ci/thirdparties_msci/build/dcmtk/.build_windows_x86_64_msvc16_md/.build_package/dcmtls/tests/privkey.pem",
            "F:/ci/thirdparties_msci/build/dcmtk/.build_windows_x86_64_msvc16_md/.build_package/dcmtls/tests/pubselfsignedcert.pem",
            "testDcmtk!",
            CertificateVerification::DCV_ignoreCertificate
        );
        if (!network->EchoRequest(server)) {
            return -1;
        }

        return 0;
    }

    int ReadDcmFileTest()
    {
        //std::filesystem::path localPath = ms::common::PathUtils::GetLocalPath();
        std::shared_ptr<IDataSet> dataset = DCMFactory::CreateDataSetInstance();
        if (!dataset->LoadDCMFile("../../local/img/rdf.dcm")) {
            return -1;
        }

        std::string SValue;
        unsigned short USValue = 0;
        double DValue = 0.0;
        const unsigned char* UCPValue = nullptr;
        const unsigned short* USPValue = nullptr;

        //Patient
        if (!dataset->Get("PatientName", SValue)) {
            return -1;
        }
        std::cout << "PatientName: " << SValue << std::endl;
        if (!dataset->Get("PatientBirthDate", SValue)) {
            return -1;
        }
        std::cout << "PatientBirthDate: " << SValue << std::endl;
        if (!dataset->Get("PatientSex", SValue)) {
            return -1;
        }
        std::cout << "PatientSex: " << SValue << std::endl;
        if (!dataset->Get("PatientID", SValue)) {
            return -1;
        }
        std::cout << "PatientID: " << SValue << std::endl;
        //General Study
        if (!dataset->Get("StudyInstanceUID", SValue)) {//internal general
            return -1;
        }
        std::cout << "StudyInstanceUID: " << SValue << std::endl;
        if (!dataset->Get("StudyDate", SValue)) {
            return -1;
        }
        std::cout << "StudyDate: " << SValue << std::endl;
        if (!dataset->Get("StudyTime", SValue)) {
            return -1;
        }
        std::cout << "StudyTime: " << SValue << std::endl;
        if (!dataset->Get("ReferringPhysicianName", SValue)) {
            return -1;
        }
        std::cout << "ReferringPhysicianName: " << SValue << std::endl;
        if (!dataset->Get("StudyID", SValue)) {
            return -1;
        }
        std::cout << "StudyID: " << SValue << std::endl;
        if (!dataset->Get("AccessionNumber", SValue)) {
            return -1;
        }
        std::cout << "AccessionNumber: " << SValue << std::endl;
        if (!dataset->Get("StudyDescription", SValue)) {
            return -1;
        }
        std::cout << "StudyDescription: " << SValue << std::endl;
        //Patient Study
        if (!dataset->Get("PatientAge", SValue)) {
            return -1;
        }
        std::cout << "PatientAge: " << SValue << std::endl;
        if (!dataset->Get("PatientWeight", SValue)) {
            return -1;
        }
        std::cout << "PatientWeight: " << SValue << std::endl;
        //General Series
        if (!dataset->Get("SeriesInstanceUID", SValue)) {//internal general
            return -1;
        }
        std::cout << "SeriesInstanceUID: " << SValue << std::endl;
        if (!dataset->Get("Modality", SValue)) {
            return -1;
        }
        std::cout << "Modality: " << SValue << std::endl;
        if (!dataset->Get("SeriesNumber", SValue)) {
            return -1;
        }
        std::cout << "SeriesNumber: " << SValue << std::endl;
        if (!dataset->Get("SeriesDate", SValue)) {
            return -1;
        }
        std::cout << "SeriesDate: " << SValue << std::endl;
        if (!dataset->Get("SeriesTime", SValue)) {
            return -1;
        }
        std::cout << "SeriesTime: " << SValue << std::endl;
        if (!dataset->Get("SeriesDescription", SValue)) {
            return -1;
        }
        std::cout << "SeriesDescription: " << SValue << std::endl;
        if (!dataset->Get("BodyPartExamined", SValue)) {
            return -1;
        }
        std::cout << "BodyPartExamined: " << SValue << std::endl;
        if (!dataset->Get("PatientPosition", SValue)) {
            return -1;
        }
        std::cout << "PatientPosition: " << SValue << std::endl;
        if (!dataset->Get("ProtocolName", SValue)) {
            return -1;
        }
        std::cout << "ProtocolName: " << SValue << std::endl;
        //General Image
        if (!dataset->Get("InstanceNumber", SValue)) {
            return -1;
        }
        std::cout << "InstanceNumber: " << SValue << std::endl;
        if (!dataset->Get("ContentDate", SValue)) {
            return -1;
        }
        std::cout << "ContentDate: " << SValue << std::endl;
        if (!dataset->Get("ContentTime", SValue)) {
            return -1;
        }
        std::cout << "ContentTime: " << SValue << std::endl;
        if (!dataset->Get("ImageType", SValue)) {
            return -1;
        }
        std::cout << "ImageType: " << SValue << std::endl;
        if (!dataset->Get("ImageComments", SValue)) {
            return -1;
        }
        std::cout << "ImageComments: " << SValue << std::endl;
        //Image Plane
        if (!dataset->Get("PixelSpacing", SValue)) {
            return -1;
        }
        std::cout << "PixelSpacing: " << SValue << std::endl;
        if (!dataset->Get("ImageOrientationPatient", SValue)) {
            return -1;
        }
        std::cout << "ImageOrientationPatient: " << SValue << std::endl;
        if (!dataset->Get("ImagePositionPatient", SValue)) {
            return -1;
        }
        std::cout << "ImagePositionPatient: " << SValue << std::endl;
        if (!dataset->Get("SliceThickness", SValue)) {
            return -1;
        }
        std::cout << "SliceThickness: " << SValue << std::endl;
        if (!dataset->Get("SliceLocation", SValue)) {
            return -1;
        }
        std::cout << "SliceLocation: " << SValue << std::endl;
        //Image Pixel
        if (!dataset->Get("PixelData", USPValue)) {//row * column
            return -1;
        }
        std::ofstream ostream("../../../local/img/readRDF", std::ios::binary);
        if (!ostream.is_open()) {
            return -1;
        }
        ostream.write((char*)USPValue, 256 * 256 * 2);
        ostream.close();
        if (!dataset->Get("SamplesPerPixel", USValue)) {
            return -1;
        }
        std::cout << "SamplesPerPixel: " << USValue << std::endl;
        if (!dataset->Get("PhotometricInterpretation", SValue)) {
            return -1;
        }
        std::cout << "PhotometricInterpretation: " << SValue << std::endl;
        if (!dataset->Get("Rows", USValue)) {
            return -1;
        }
        std::cout << "Rows: " << USValue << std::endl;
        if (!dataset->Get("Columns", USValue)) {
            return -1;
        }
        std::cout << "Columns: " << USValue << std::endl;
        if (!dataset->Get("BitsAllocated", USValue)) {
            return -1;
        }
        std::cout << "BitsAllocated: " << USValue << std::endl;
        if (!dataset->Get("BitsStored", USValue)) {
            return -1;
        }
        std::cout << "BitsStored: " << USValue << std::endl;
        if (!dataset->Get("HighBit", USValue)) {
            return -1;
        }
        std::cout << "HighBit: " << USValue << std::endl;
        if (!dataset->Get("PixelRepresentation", USValue)) {
            return -1;
        }
        std::cout << "PixelRepresentation: " << USValue << std::endl;
        //MR Image
        if (!dataset->Get("SequenceName", SValue)) {
            return -1;
        }
        std::cout << "SequenceName: " << SValue << std::endl;
        if (!dataset->Get("FlipAngle", SValue)) {
            return -1;
        }
        std::cout << "FlipAngle: " << SValue << std::endl;
        if (!dataset->Get("EchoNumbers", SValue)) {
            return -1;
        }
        std::cout << "EchoNumbers: " << SValue << std::endl;
        if (!dataset->Get("RepetitionTime", SValue)) {
            return -1;
        }
        std::cout << "RepetitionTime: " << SValue << std::endl;
        if (!dataset->Get("PixelBandwidth", SValue)) {
            return -1;
        }
        std::cout << "PixelBandwidth: " << SValue << std::endl;
        if (!dataset->Get("TransmitCoilName", SValue)) {
            return -1;
        }
        std::cout << "TransmitCoilName: " << SValue << std::endl;
        if (!dataset->Get("NumberOfAverages", SValue)) {
            return -1;
        }
        std::cout << "NumberOfAverages: " << SValue << std::endl;
        if (!dataset->Get("AcquisitionMatrix", USPValue)) {
            return -1;
        }
        std::cout << "AcquisitionMatrix: " << USPValue[0] << std::endl;
        if (!dataset->Get("InPlanePhaseEncodingDirection", SValue)) {
            return -1;
        }
        std::cout << "InPlanePhaseEncodingDirection: " << SValue << std::endl;
        if (!dataset->Get("EchoTime", SValue)) {
            return -1;
        }
        std::cout << "EchoTime: " << SValue << std::endl;
        if (!dataset->Get("InversionTime", SValue)) {
            return -1;
        }
        std::cout << "InversionTime: " << SValue << std::endl;
        if (!dataset->Get("AcquisitionDuration", DValue)) {
            return -1;
        }
        std::cout << "AcquisitionDuration: " << DValue << std::endl;
        //SOP Common
        if (!dataset->Get("SOPInstanceUID", SValue)) {//internal general
            return -1;
        }
        std::cout << "SOPInstanceUID: " << SValue << std::endl;
        if (!dataset->Get("SOPClassUID", SValue)) {
            return -1;
        }
        std::cout << "SOPClassUID: " << SValue << std::endl;
        if (!dataset->Get("SpecificCharacterSet", SValue)) {//ISO_IR 192 == utf-8
            return -1;
        }
        std::cout << "SpecificCharacterSet: " << SValue << std::endl;
        //VOI LUT
        if (!dataset->Get("WindowCenter", SValue)) {
            return -1;
        }
        std::cout << "WindowCenter: " << SValue << std::endl;
        if (!dataset->Get("WindowWidth", SValue)) {
            return -1;
        }
        std::cout << "WindowWidth: " << SValue << std::endl;
        //Frame of Reference
        if (!dataset->Get("FrameOfReferenceUID", SValue)) {
            return -1;
        }
        std::cout << "FrameOfReferenceUID: " << SValue << std::endl;
        if (!dataset->Get("PositionReferenceIndicator", SValue)) {
            return -1;
        }
        std::cout << "PositionReferenceIndicator: " << SValue << std::endl;
        //General Equipment
        if (!dataset->Get("Manufacturer", SValue)) {
            return -1;
        }
        std::cout << "Manufacturer: " << SValue << std::endl;
        if (!dataset->Get("InstitutionName", SValue)) {
            return -1;
        }
        std::cout << "InstitutionName: " << SValue << std::endl;
        if (!dataset->Get("ManufacturerModelName", SValue)) {
            return -1;
        }
        std::cout << "ManufacturerModelName: " << SValue << std::endl;
        //General Acquisition
        if (!dataset->Get("AcquisitionNumber", SValue)) {
            return -1;
        }
        std::cout << "AcquisitionNumber: " << SValue << std::endl;
        if (!dataset->Get("AcquisitionDate", SValue)) {
            return -1;
        }
        std::cout << "AcquisitionDate: " << SValue << std::endl;
        if (!dataset->Get("AcquisitionTime", SValue)) {
            return -1;
        }
        std::cout << "AcquisitionTime: " << SValue << std::endl;
        //Private
        std::string privateCreator = "marvelstone";
        if (!dataset->GetPrivate("PRIVATE_CREATOR_MARVELSTONE", privateCreator, SValue)) {
            return -1;
        }
        std::cout << "PRIVATE_CREATOR_MARVELSTONE: " << SValue << std::endl;
        if (!dataset->GetPrivate("PRIVATE_RDFDATAFORMAT", privateCreator, USValue)) {
            return -1;
        }
        std::cout << "PRIVATE_RDFDATAFORMAT: " << USValue << std::endl;
        if (!dataset->GetPrivate("PRIVATE_RDFPARAMETER", privateCreator, SValue)) {
            return -1;
        }
        std::cout << "PRIVATE_RDFPARAMETER: " << SValue << std::endl;
        if (!dataset->GetPrivate("PRIVATE_SCANID", privateCreator, SValue)) {
            return -1;
        }
        std::cout << "PRIVATE_SCANID: " << SValue << std::endl;

        return 0;
    }

    void StoreCallback(const NetworkStatus aStatus, const double aCompletePercent, const std::string& aDescription)
    {
        if (aStatus == NetworkStatus::Start) {
            std::cout << "store begin" << std::endl;
        } else if (aStatus == NetworkStatus::Pending) {
            std::cout << "store pending: " << aCompletePercent << "%" << std::endl;
        } else if (aStatus == NetworkStatus::End) {
            std::cout << "store end" << std::endl;
        }
    }

    int StoreTestWithDCMFile()
    {
        std::shared_ptr<INetwork> network = DCMFactory::CreateNetworkInstance();

        ServerInfo server;
        server.myHost = "127.0.0.1";
        server.myPort = "5678";
        server.myTitle = "IHEFULL";
        network->BindStoreCallback(StoreCallback);
        if (!network->StoreRequest(server, "../../../local/img/rdf.dcm")) {
            return -1;
        }
        return 0;
    }

    int StoreTestWithDataset()
    {
        std::shared_ptr<INetwork> network = DCMFactory::CreateNetworkInstance();
        std::shared_ptr<IDataSet> dataset = DCMFactory::CreateDataSetInstance();

        std::ifstream iodStream("../../../local/config/mr_iod.json");
        if (!iodStream.is_open()) {
            return -1;
        }
        std::istreambuf_iterator<char> beg(iodStream), end;
        std::string str(beg, end);
        iodStream.close();

        if (!dataset->ParseIODString(str)) {
            return -1;
        }

        //Patient
        if (!dataset->Set("PatientName", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientBirthDate", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientSex", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientID", "test")) {
            return -1;
        }
        //General Study
        if (!dataset->Set("StudyInstanceUID")) {//internal general
            return -1;
        }
        if (!dataset->Set("StudyDate", "test")) {
            return -1;
        }
        if (!dataset->Set("StudyTime", "test")) {
            return -1;
        }
        if (!dataset->Set("ReferringPhysicianName", "test")) {
            return -1;
        }
        if (!dataset->Set("StudyID", "test")) {
            return -1;
        }
        if (!dataset->Set("AccessionNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("StudyDescription", "test")) {
            return -1;
        }
        //Patient Study
        if (!dataset->Set("PatientAge", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientWeight", "test")) {
            return -1;
        }
        //General Series
        if (!dataset->Set("SeriesInstanceUID")) {//internal general
            return -1;
        }
        if (!dataset->Set("Modality", "MR")) {
            return -1;
        }
        if (!dataset->Set("SeriesNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("SeriesDate", "test")) {
            return -1;
        }
        if (!dataset->Set("SeriesTime", "test")) {
            return -1;
        }
        if (!dataset->Set("SeriesDescription", "test")) {
            return -1;
        }
        if (!dataset->Set("BodyPartExamined", "test")) {
            return -1;
        }
        if (!dataset->Set("PatientPosition", "test")) {
            return -1;
        }
        if (!dataset->Set("ProtocolName", "test")) {
            return -1;
        }
        //General Image
        if (!dataset->Set("InstanceNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("ContentDate", "test")) {
            return -1;
        }
        if (!dataset->Set("ContentTime", "test")) {
            return -1;
        }
        if (!dataset->Set("ImageType", "ORIGINAL\\PRIMARY")) {
            return -1;
        }
        if (!dataset->Set("ImageComments", "test")) {
            return -1;
        }
        //Image Plane
        if (!dataset->Set("PixelSpacing", "test")) {
            return -1;
        }
        if (!dataset->Set("ImageOrientationPatient", "test")) {
            return -1;
        }
        if (!dataset->Set("ImagePositionPatient", "test")) {
            return -1;
        }
        if (!dataset->Set("SliceThickness", "test")) {
            return -1;
        }
        if (!dataset->Set("SliceLocation", "test")) {
            return -1;
        }
        //Image Pixel
        std::ifstream istream("../../../local/img/rdf", std::ios::binary);
        if (!istream.is_open()) {
            return -1;
        }
        istream.seekg(0, std::ios_base::end);
        std::streamoff dataSize = istream.tellg();
        char* data = new char[dataSize];
        if (nullptr == data) {
            return-1;
        }
        istream.seekg(0, std::ios_base::beg);
        istream.read(data, dataSize);
        istream.close();
        if (!dataset->Set("PixelData", (unsigned short*)data, (unsigned long)(256 * 256))) {//row * column
            return -1;
        }
        if (!dataset->Set("SamplesPerPixel", (unsigned short)1)) {
            return -1;
        }
        if (!dataset->Set("PhotometricInterpretation", "MONOCHROME2")) {
            return -1;
        }
        if (!dataset->Set("Rows", (unsigned short)256)) {
            return -1;
        }
        if (!dataset->Set("Columns", (unsigned short)256)) {
            return -1;
        }
        if (!dataset->Set("BitsAllocated", (unsigned short)16)) {
            return -1;
        }
        if (!dataset->Set("BitsStored", (unsigned short)16)) {
            return -1;
        }
        if (!dataset->Set("HighBit", (unsigned short)15)) {
            return -1;
        }
        if (!dataset->Set("PixelRepresentation", (unsigned short)0)) {
            return -1;
        }
        //MR Image
        if (!dataset->Set("SequenceName", "test")) {
            return -1;
        }
        if (!dataset->Set("FlipAngle", "test")) {
            return -1;
        }
        if (!dataset->Set("EchoNumbers", "test")) {
            return -1;
        }
        if (!dataset->Set("RepetitionTime", "test")) {
            return -1;
        }
        if (!dataset->Set("PixelBandwidth", "test")) {
            return -1;
        }
        if (!dataset->Set("TransmitCoilName", "test")) {
            return -1;
        }
        if (!dataset->Set("NumberOfAverages", "test")) {
            return -1;
        }
        unsigned short am[] = { 1,2 };
        if (!dataset->Set("AcquisitionMatrix", am, 2)) {
            return -1;
        }
        if (!dataset->Set("InPlanePhaseEncodingDirection", "test")) {
            return -1;
        }
        if (!dataset->Set("EchoTime", "test")) {
            return -1;
        }
        if (!dataset->Set("InversionTime", "test")) {
            return -1;
        }
        if (!dataset->Set("AcquisitionDuration", 1.1)) {
            return -1;
        }
        //SOP Common
        if (!dataset->Set("SOPInstanceUID")) {//internal general
            return -1;
        }
        if (!dataset->Set("SOPClassUID", "test")) {
            return -1;
        }
        if (!dataset->Set("SpecificCharacterSet", "ISO_IR 192")) {//ISO_IR 192 == utf-8
            return -1;
        }
        //VOI LUT
        if (!dataset->Set("WindowCenter", "0")) {
            return -1;
        }
        if (!dataset->Set("WindowWidth", "0")) {
            return -1;
        }
        //Frame of Reference
        if (!dataset->Set("FrameOfReferenceUID", "test")) {
            return -1;
        }
        if (!dataset->Set("PositionReferenceIndicator", "test")) {
            return -1;
        }
        //General Equipment
        if (!dataset->Set("Manufacturer", "test")) {
            return -1;
        }
        if (!dataset->Set("InstitutionName", "test")) {
            return -1;
        }
        if (!dataset->Set("ManufacturerModelName", "test")) {
            return -1;
        }
        //General Acquisition
        if (!dataset->Set("AcquisitionNumber", "test")) {
            return -1;
        }
        if (!dataset->Set("AcquisitionDate", "test")) {
            return -1;
        }
        if (!dataset->Set("AcquisitionTime", "test")) {
            return -1;
        }
        //Private
        std::string privateCreator = "marvelstone";
        if (!dataset->SetPrivate("PRIVATE_CREATOR_MARVELSTONE", privateCreator)) {
            return -1;
        }
        if (!dataset->SetPrivate("PRIVATE_RDFDATAFORMAT", privateCreator, (unsigned short)3)) {
            return -1;
        }
        if (!dataset->SetPrivate("PRIVATE_RDFPARAMETER", privateCreator, "test")) {
            return -1;
        }
        if (!dataset->SetPrivate("PRIVATE_SCANID", privateCreator, "test")) {
            return -1;
        }

        ServerInfo server;
        server.myHost = "127.0.0.1";
        server.myPort = "5678";
        server.myTitle = "IHEFULL";
        network->BindStoreCallback(StoreCallback);
        if (!network->StoreRequest(server, dataset)) {
            return -1;
        }
        return 0;
    }

    int PrintTest()
    {
        std::shared_ptr<IDCMPrint> printer = DCMFactory::CreatePrintInstance("../../../local/font/simhei.ttf");

        //init network
        ServerInfo server;
        server.myHost = "127.0.0.1";
        server.myPort = "5678";
        server.myTitle = "IHEFULL";
        if (!printer->InitNetwork(server)) {
            return -1;
        }

        //create film session box
        FilmSessionBoxModule sessionBox;
        sessionBox.myMediuType = "PAPER";
        sessionBox.myNumberofCopies = "2";
        sessionBox.myFilmPriority = "MED";
        sessionBox.myFilmDestination = "PROCESSOR";
        if (!printer->CreateFilmSessionBox(sessionBox)) {
            return -1;
        }

        //create film box
        bool anno = false;
        bool lut = false;
        FilmBoxModule filmBox;
        filmBox.myFilmBoxNumber = 1;
        filmBox.myAnnotationDisplayFormatID = "LABEL";
        filmBox.myImageDisplayFormat = "STANDARD\\1,1";
        filmBox.myFilmOrientation = "PORTRAIT";
        filmBox.myFilmSizeID = "A4";
        filmBox.myMagnificationType = "REPLICATE";
        filmBox.myRequestedResolutionID = "HIGH";
        if (!printer->CreateFilmBox(filmBox, anno, lut)) {
            return -1;
        }

        //create screenshot
        char* data1 = nullptr;
        std::ifstream f1("../../../local/img/002", std::ios::binary);
        if (!f1.is_open()) {
            return false;
        }
        f1.seekg(0, std::ios::end);
        unsigned long size1 = static_cast<unsigned long>(f1.tellg());
        data1 = new char[size1];
        if (nullptr == data1) {
            return 0;
        }
        f1.seekg(0, std::ios::beg);
        f1.read(data1, size1);

        ImageParameter param;
        param.myColumns = 304;
        param.myRows = 304;
        param.myWindowsCenter = 945;
        param.myWindowsWidth = 1880;
        //if param.myPixelData == nullptr,CreateOpenCVImage() will create a empty image
        param.myPixelData = data1;
        param.myPixelSpacingY = 0.78947371200000;

        CornerInfoV corner;
        corner.myLeftTop = { "2023/02/09","18.39.18","22岁","20000303","3435435","测试","男","0","33","1/1 1(1)/32","54352023020918020651" };
        //arrow_left, arrow_right, arrow_top, arrow_bottom
        corner.myRightTop = { "MS","中低场","Head supine","arrow_bottom" };
        corner.myLeftBottom = { "MF 1.0", "TR 15","TE 4.76","FA 25","TA 00:02:02","BW 160","NEX 1","Head8","gre3d" };
        corner.myRightBottom = { "SP -37.5","SL 3/0","FoV 256*256","Axial","W 909","C 437" };
        corner.myLeftCenter = { "A" };
        corner.myBottomCenter = { "B" };
        corner.myRightCenter = { "C" };
        corner.myTopCenter = { "D" };

        for (int i = 0; i < 3; ++i) {
            if (!printer->CreateOpenCVImage(param, corner)) {
                return -1;
            }
        }
        delete[] data1;

        HeaderInfo header;
        header.myWidthNum = 2;
        header.myHeightNum = 2;
        header.myPageNumber = "1/8";
        header.myPatientAge = "22岁";
        header.myPatientID = "3435435";
        header.myPatientName = "测试";
        header.myPatientSex = "男";

        std::string path = "../../../local/img/print.raw";

        if (!printer->SplicingOpenCVImage(header, CVType::cv_8UC3, path)) {
            return -1;
        }

        //create printer
        /*PrinterModule printerM;
        if (!printer->GetPrinterInfo(printerM)) {
            return -1;
        }*/

        /*PrinterConfigurationModule aPrinterConfiguration;
        if (!printer->GetPrinterConfiguration(aPrinterConfiguration)) {
            return -1;
        }*/

        if (lut) {
            PresentationLUTModule lut;
            lut.myLUTData = nullptr;
            lut.myLUTDescriptor = nullptr;
            lut.myPresentationLUTShape = "IDENTITY";
            if (printer->CreatePresentationLUT(lut, 0)) {
                return -1;
            }
        }

        //create image box
        ImageBoxModule imageBox;
        imageBox.myBitsAllocated = 8;
        imageBox.myRows = 2500;
        imageBox.myColumns = 2400;
        imageBox.myPhotometricInterpretation = "RGB";
        //Rows / Columns
        std::string ratio = std::to_string(imageBox.myRows) + "\\" + std::to_string(imageBox.myColumns);
        imageBox.myPixelAspectRatio = ratio;
        imageBox.myPixelRepresentation = 0;
        imageBox.mySamplesPerPixel = 3;

        char* data = nullptr;
        std::ifstream f(path, std::ios::binary);
        if (!f.is_open()) {
            return false;
        }
        f.seekg(0, std::ios::end);
        unsigned long size = static_cast<unsigned long>(f.tellg());
        data = new char[size];
        if (nullptr == data) {
            return 0;
        }
        f.seekg(0, std::ios::beg);
        f.read(data, size);

        imageBox.myPixelData = data;

        //must start with 0, 2 * 2 = displayformat
        for (int i = 0; i < 1 * 1; ++i) {
            imageBox.myImageBoxPosition = i;
            if (!printer->SetImageBox(imageBox, filmBox.myFilmBoxNumber)) {
                return -1;
            }
        }

        if (anno) {
            AnnotationBoxModule  anno;
            anno.myAnnotationPosition = 1;
            anno.myTextString = "anno";
            if (!printer->SetAnnotationBox(anno)) {
                return -1;
            }
        }

        /*PrintJobModule printJob;
        if (!printer->GetPrintJob(printJob)) {
            return -1;
        }*/

        //PrintFilmBox: print last film
        //PrintFilmSessionBox: print all film
        if (!printer->PrintFilmBox(filmBox.myFilmBoxNumber)) {
            return -1;
        }

        delete data;

        //delete all box
        if (!printer->DeleteAllBox()) {
            return -1;
        }

        //release
        if (!printer->ReleaseNetwork()) {
            return -1;
        }

        return 0;
    }

    int OverlayTest()
    {
        std::shared_ptr<IImage> image = DCMFactory::CreateImageInstance("../../../local/img/rdf.dcm");

        Overlay overlay;
        overlay.myColumns = 256;
        overlay.myRows = 256;
        //G​:Graphics​, R​:ROI​
        overlay.myType = "R";
        //row/column
        overlay.myOrigin = overlay.myRows / overlay.myColumns;
        overlay.myDescription = "overlay test";
        unsigned char* data = nullptr;
        std::ifstream f1("../../../local/img/002", std::ios::binary);
        if (!f1.is_open()) {
            return false;
        }
        f1.seekg(0, std::ios::end);
        unsigned long size1 = static_cast<unsigned long>(f1.tellg());
        data = new unsigned char[size1];
        if (nullptr == data) {
            return 0;
        }
        f1.seekg(0, std::ios::beg);
        f1.read((char*)data, size1);
        overlay.myData = data;

        if (!image->AddOverlay(overlay)) {
            return -1;
        }
        if (!image->GeneralDCMFile("../../../local/img/overlay.dcm", DCM_TransferSyntax::EXS_LittleEndianExplicit)) {
            return -1;
        }

        delete data;
        return 0;
    }

    int JPEGTest()
    {
        std::shared_ptr<IImage> image = DCMFactory::CreateImageInstance();

        if (!image->JPEGCompress("../../../local/img/rdf.dcm", "../../../local/img/jpeg_compress.dcm", DCM_TransferSyntax::EXS_JPEGProcess14SV1)) {
            return false;
        }
        if (!image->JPEGDecompress("../../../local/img/jpeg_compress.dcm", "../../../local/img/jpeg_deCompress.dcm", DCM_TransferSyntax::EXS_LittleEndianExplicit)) {
            return false;
        }

        return 0;
    }

} // anonymous namespace

namespace ms::test {
    TEST_F(DicomTools, StoreTestWithDCMFile)
    {
        //EXPECT_EQ(StoreTestWithDCMFile(), 0);
    }
    TEST_F(DicomTools, StoreTestWithDataset)
    {
        //EXPECT_EQ(StoreTestWithDataset(), 0);
    }
    TEST_F(DicomTools, WorklistTest)
    {
        //EXPECT_EQ(WorklistTest(), 0);
    }
    TEST_F(DicomTools, EchoTest)
    {
        EXPECT_EQ(EchoTest(), 0);
    }
    TEST_F(DicomTools, EchoTLSTest)
    {
        //EXPECT_EQ(EchoTLSTest(), 0);
    }
    TEST_F(DicomTools, PrintTest)
    {
        //EXPECT_EQ(PrintTest(), 0);
    }
    TEST_F(DicomTools, RDF2DcmTest)
    {
        //EXPECT_EQ(RDF2DcmTest(), 0);
    }
    TEST_F(DicomTools, ReadDcmFileTest)
    {
        //EXPECT_EQ(ReadDcmFileTest(), 0);
    }
    TEST_F(DicomTools, OverlayTest)
    {
        //EXPECT_EQ(OverlayTest(), 0);
    }
    TEST_F(DicomTools, JPEGTest)
    {
        //EXPECT_EQ(JPEGTest(), 0);
    }
} // namespace "ms::test"
